package cn.test.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Objects;

public class NumberUtil {

    private NumberUtil() {
    }

    public static String formatNum(BigDecimal value, int point) {
        if (Objects.isNull(value)) {
            return "";
        }
        value = value.setScale(point, RoundingMode.HALF_UP);
        if (BigDecimal.ZERO.compareTo(value) == 0) {
            return value.toPlainString();
        }
        DecimalFormat df = new DecimalFormat(getFormatDefinition(point));
        return df.format(value);
    }

    public static String formatNum(BigDecimal value) {
        if (Objects.isNull(value)) {
            return "";
        }
        if (BigDecimal.ZERO.compareTo(value) == 0) {
            return value.toPlainString();
        }
        int point = value.stripTrailingZeros().scale();
        DecimalFormat df = new DecimalFormat(getFormatDefinition(point));
        return df.format(value);
    }

    public static String formatThd(BigDecimal value, int point) {
        if (value == null) {
            return "";
        }
        value = value.setScale(point, RoundingMode.HALF_UP);
        if (BigDecimal.ZERO.compareTo(value) == 0) {
            return value.toPlainString();
        }
        DecimalFormat df = new DecimalFormat(getThdFormatDefinition(point));
        return df.format(value);
    }

    public static String formatThdByPara(BigDecimal value) {
        if (value == null) {
            return "";
        }
        if (BigDecimal.ZERO.compareTo(value) == 0) {
            return value.toPlainString();
        }
        int point = value.stripTrailingZeros().scale();
        DecimalFormat df = new DecimalFormat(getThdFormatDefinition(point));
        return df.format(value);
    }

    public static String int2chineseNum(int src) {
        final String[] num = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        final String[] unit = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千"};
        String dst = "";
        int count = 0;
        while (src > 0) {
            dst = String.format("%s%s%s", num[src % 10], unit[count], dst);
            src = src / 10;
            count++;
        }
        return dst.replaceAll("零[千百十]", "零").replaceAll("零+万", "万")
                .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
                .replaceAll("零+", "零").replaceAll("零$", "");
    }

    public static String percentFormat(BigDecimal value, int point) {
        if (Objects.isNull(value)) {
            return "";
        }
        value = value.setScale(point + 2, RoundingMode.HALF_UP);
        if (BigDecimal.ZERO.compareTo(value) == 0) {
            return value.toPlainString();
        }
        return new DecimalFormat(getPercentFormatDefinition(point)).format(value);
    }

    public static String thousandthFormat(BigDecimal value, int point) {
        if (Objects.isNull(value)) {
            return "";
        }
        value = value.setScale(point + 3, RoundingMode.HALF_UP);
        if (BigDecimal.ZERO.compareTo(value) == 0) {
            return value.toPlainString();
        }
        DecimalFormat df = new DecimalFormat(getThousandthFormatDefinition(point));
        return df.format(value);
    }

    private static String getFormatDefinition(int pointNum) {
        StringBuilder formatDefinition = new StringBuilder("#0");
        if (pointNum < 1) {
            return formatDefinition.toString();
        }
        formatDefinition.append(".");
        for (int i = 0; i < pointNum; i++) {
            formatDefinition.append("0");
        }
        return formatDefinition.toString();
    }

    private static String getThdFormatDefinition(int pointNum) {
        StringBuilder thdFormatDefinition = new StringBuilder(",##0");
        if (pointNum < 1) {
            return thdFormatDefinition.toString();
        }
        thdFormatDefinition.append(".");
        for (int i = 0; i < pointNum; i++) {
            thdFormatDefinition.append("0");
        }
        return thdFormatDefinition.toString();
    }

    private static String getPercentFormatDefinition(int pointNum) {
        StringBuilder percentDefinition = new StringBuilder("0");
        if (pointNum < 1) {
            return percentDefinition.toString();
        }
        percentDefinition.append(".");
        for (int i = 0; i < pointNum; i++) {
            percentDefinition.append("0");
        }
        return percentDefinition.append("%").toString();
    }

    private static String getThousandthFormatDefinition(int pointNum) {
        StringBuilder thousandDefinition = new StringBuilder("0");
        if (pointNum < 1) {
            return thousandDefinition.toString();
        }
        thousandDefinition.append(".");
        for (int i = 0; i < pointNum; i++) {
            thousandDefinition.append("0");
        }
        return thousandDefinition.append("\u2030").toString();
    }
}
